package sanmubird.club.v8.Stream;

import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 流处理要达到一种效果：
 * 不需要写出具体该怎么做，只需要表达想要什么。
 * 就像sql一样 select * from table, 我们不需要告诉具体该怎么查,只需要表达清楚查询结果就可以。
 * 流是Java API的新成员，它允许你以声明性方式处理数据?合（通过查?语句来表达，而不是临时编写一个实现）
 * 流到底是什么呢？简短的定义就是“从支持数据处理操作的源生成的元素序列”。
 * <p>
 * 使用流的好处： 流是一种内部迭代，  for_each 是一种外部迭代 。
 * 内部迭代 可以自动选择一种适合硬件的数据表示和并行实现。 外部迭代 就需要自己管理所有的并行问题。
 */
public class StreamStarter {

	@Test
	public void t() {
		Stream<Dish> stream = Stream.of(
				new Dish("pork", false, 800, Dish.Type.MEAT),
				new Dish("beef", false, 700, Dish.Type.MEAT),
				new Dish("chicken", false, 400, Dish.Type.MEAT),
				new Dish("french fries", true, 530, Dish.Type.OTHER),
				new Dish("rice", true, 350, Dish.Type.OTHER),
				new Dish("season fruit", true, 120, Dish.Type.OTHER),
				new Dish("pizza", true, 550, Dish.Type.OTHER),
				new Dish("prawns", false, 300, Dish.Type.FISH),
				new Dish("salmon", false, 450, Dish.Type.FISH));

		// 过滤 跳出 热量在 300 卡里路 以上的 再按照卡里路值从高到低的顺序排序，再取前三个， 再取出名字 组成 list
		List<String> threeHighCaloricDishNames =
				stream.filter(d -> d.getCalories() > 300).sorted(Comparator.comparing(Dish::getCalories).reversed()).limit(3).map(Dish::getName).collect(Collectors.toList());
		System.out.println(threeHighCaloricDishNames);
	}

	@Test
	public void tt() {
		String path = new File(ClassLoader.getSystemResource("").getPath()).getPath();
		try (Stream<String> lines = Files.lines(Paths.get(path, "data.txt"), Charset.defaultCharset());) {
			List<Integer> collect = lines.map(String::length).collect(Collectors.toList());
			System.out.println(collect);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

@Getter
@AllArgsConstructor
@ToString
@EqualsAndHashCode
class Dish {
	private final String name;
	private final boolean vegetarian;
	private final int calories;
	private final Type type;

	public enum Type {MEAT, FISH, OTHER}
}